home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / asm3.zip / QUICKEYS.ASM < prev    next >
Assembly Source File  |  1985-12-11  |  9KB  |  144 lines

  1. TITLE QUICKEYS 
  2.  
  3. COMMENT | This memory resident routine augments the typematic key repetition
  4.           feature of the IBM PC, XT, and AT.  Upon each keystroke interrupt,
  5.           QUICKEYS resets itself, then calls the standard keystroke routines for
  6.           processing.  Upon return to QUICKEYS, if a new keystroke has been
  7.           stored in the ROM BIOS keyboard buffer, it is memorized and a count-
  8.           down is begun.  If not reset by release of the key, the key will be
  9.           repeated in the buffer after a delay of DUP_DELAY1 timer ticks and
  10.           then again every DUP_DELAY2 ticks thereafter, until the key is
  11.           released.
  12.  
  13.           Timer delay settings of 9 and 2 for DUP_DELAY1 and DUP_DELAY2 are
  14.           effectively equivalent to the standard IBM PC typematic settings for
  15.           the delay before the first repeat of a held-down key and for the delay
  16.           between subsequent repetions of it while the key remains down.
  17.  
  18.           Press the (Alt) and left (Shift) keys together, to empty the buffer
  19.           if too many keystrokes have been entered.  Handy way to get around
  20.           spread sheet is to fill buffer with cursor keys and then zap excess
  21.           with (ALT)(Shift) when arrive where wanted to go.
  22.  
  23.           Copyright 1986 - Ziff-Davis Publishing Company
  24.                                                                               |
  25. BIOS_SEG       SEGMENT AT 40H             ;ESTABLISH BIOS SEG
  26. BIOS_SEG       ENDS                          ;ADDRESS.
  27.  
  28. CSEG   SEGMENT
  29.        ASSUME  CS:CSEG                 ;WHEN RESIDENT, NOT SURE OF DS OR ES.
  30.        ORG     100H                    ;STD CODE OFFSET FOR COM FILES.
  31. BEGIN:         JMP     INITIALIZE      ;GO SET VECTORS, WHEN LOADED BY DOS.
  32. ROM_INT8       DW      ?,?             ;ORIGINAL TIMER VECTOR ADDRESS
  33. ROM_INT9       DW      ?,?             ;ORIGINAL KEYSTROKE VECTOR ADDR
  34. DUP_CHAR       DW      ?               ;CHAR TO BE REPEATED NEXT.
  35. DUP_SWTCH      DB      0               ;1, IF CHAR IS TO BE REPEATED
  36. DUP_CNT        DB      0               ;TIMER TICKS LEFT B/4 REPEAT KEY
  37. DUP_DELAY1     DB      7               ;# TICKS B/4 1ST REPEAT OF A KEY.
  38. DUP_DELAY2     DB      1               ;# TICKS DELAY BETWEEN REPEATS.
  39. ALT_SHFT       EQU     0AH             ;BITS SET WHEN IN ALT-LEFT_SHIFT STATE.
  40. BIOS_KBFLAGS   EQU     17H             ;BIOS OFFSET TO KEYBOARD SHIFT FLAGS.
  41. BIOS_HEAD      EQU     1AH             ;BIOS BUFFER ADDRESS OF NEXT OUTPUT KEY.
  42. BIOS_TAIL      EQU     1CH             ;BIOS BUFFER ADDRESS FOR NEXT INPUT KEY.
  43. BIOS_END       EQU     3EH             ;ENDING LOCATION OF BIOS KEYBOARD BUFFER.
  44. BIOS_START     EQU     1EH             ;START  LOCATION OF BIOS KEYBOARD BUFFER.
  45. ;*****************************************************************************
  46. INT9:                           ;KEYSTROKE INTERRUPT PROCESSING
  47. ;*****************************************************************************
  48.        PUSH    DS                      ;SAVE CALLER'S DATA SEGMENT ADDRESS
  49.        PUSH    BX                      ;SAVE, SO CAN USE TO STORE CURRENT TAIL.
  50.        MOV     BX,BIOS_SEG             ;SET UP ADDRESSING TO BIOS DATA SEGMENT.
  51.        MOV     DS,BX
  52.        ASSUME  DS:BIOS_SEG
  53.        MOV     DUP_SWTCH,0             ;TURN OFF AUTOMATIC KEY REPETITIONS.
  54.        MOV     BX,DS:[BIOS_TAIL]       ;SAVE CURRENT KEYBOARD TAIL LOCATION.
  55.        PUSHF                           ;CALL ROM BIOS KEYSTROKE PROCESSING
  56.        CALL    DWORD PTR ROM_INT9      ; INTERRUPT, AND RETURN HERE WHEN DONE.
  57.        CMP     BX,DS:[BIOS_TAIL]       ;IF NEW CHARACTER ENTERED, TAIL MOVED.
  58.        JNE     WAS_NEW_KEY             ;IF NOT MOVED, SET DUP_CHAR SO WILL NOT
  59.        MOV     DUP_CHAR,-1             ;MATCH ANY KEY PUSHED NEXT TIME.
  60.        TEST    BYTE PTR DS:[BIOS_KBFLAGS],ALT_SHFT ;SEE IF WAS (ALT)(SHIFT).
  61.        JZ      KEY_RETURN              ;IF SO, EMPTY THE BIOS BUFFER BY MOVING
  62.        MOV     DS:[BIOS_HEAD],BX       ;THE HEAD POINTER TO THE TAIL.
  63.        JMP     KEY_RETURN              ;     ALL DONE FOR NOW.
  64. WAS_NEW_KEY:                           ;IF TAIL HAS MOVED, HAVE NEW KEY, SO
  65.        MOV     BX,[BX]                 ;GET CHARACTER NOW STORED IN OLD TAIL.
  66.        CMP     BX,DUP_CHAR             ;COMPARE WITH PRIOR REPEAT CHARACTER AND
  67.        MOV     DUP_CHAR,BX             ;STORE AS NEW REPEAT KEY.  ASSUME OLD AND
  68.        MOV     BL,DUP_DELAY1           ;NEW CHARS DIFFERENT, SO WILL START SLOW.
  69.        JNE     SWITCH_ON               ;OTHERWISE, THIS INTERRUPT WAS FROM STD
  70.        MOV     BL,DUP_DELAY2           ;TYPEMATIC ACTION, SO STAY AT HI RATE.
  71. SWITCH_ON:
  72.        MOV     DUP_CNT,BL              ;SET REPETITION RATE FOR THE KEY AND
  73.        MOV     DUP_SWTCH,1             ;TURN TICK COUNTER BACK ON.
  74. KEY_RETURN:
  75.        POP     BX                      ;ALL DONE.  KEY HAS BEEN PROCESSED BY
  76.        POP     DS                      ;ROM BIOS; REPEAT FLAG NOW RESET AND
  77.        IRET                            ;TICK COUNT READY.  RETURN TO USER.
  78. ;*****************************************************************************
  79. INT8:                          ;TIMER INTERRUPT PROCESSING
  80. ;*****************************************************************************
  81.  
  82.        CMP     DUP_SWTCH,1             ;MOVE ON TO STANDARD TIMER PROCESSING, IF
  83.        JNE     MOVE_ON                 ;AUTOMATIC REPEAT FLAG IS NOT ON OR THE
  84.        DEC     DUP_CNT                 ;TIMER TICK COUNT IS NOT ZERO YET.
  85.        JNZ     MOVE_ON                 ;
  86.        PUSH    DS                      ;TIME TO REPEAT THE DUP_CHAR KEY, SO
  87.        PUSH    DI                      ; (1) SAVE ES,DI,BX,AND AX, SO CAN USE
  88.        PUSH    BX                      ;          TO DO THE STORING.
  89.        PUSH    AX                      ;
  90.        MOV     BX,BIOS_SEG             ; (2) ESTABLISH BIOS DATA SEGMENT
  91.        MOV     DS,BX                   ;     ADDRESSABILITY.
  92.        MOV     BX,DS:[BIOS_TAIL]       ; (3) GET CURRENT TAIL LOCATION INTO BX.
  93.        MOV     DI,BX                   ; (4) SAVE POINTER, SO CAN FILL, IF ROOM.
  94.        ADD     BX,2                    ; (5) MOVE TAIL POINTER TO NEXT WORD IN
  95.        CMP     BX,BIOS_END             ;     ROM BUFFER.
  96.        JNE     FULL_CHECK              ; (6) IF NEXT LOCATION IS PAST END OF
  97.        MOV     BX,BIOS_START           ;     BUFFER, WRAP AROUND TO START LOC.
  98. FULL_CHECK:                            ;
  99.        CMP     BX,DS:[BIOS_HEAD]       ; (7) IF NEW TAIL IS SAME AS HEAD, THERE
  100.        JNE     HAVE_ROOM               ;     ISN'T ROOM FOR ANOTHER CHAR,
  101.        MOV     DUP_SWTCH,0             ;     SO STOP REPEATING IT.
  102.        JMP     REG_RESTORE
  103. HAVE_ROOM:
  104.        CLI
  105.        MOV     AX,DUP_CHAR             ; (8) IF ROOM LEFT, MOVE THE REPEAT KEY
  106.        MOV     [DI],AX                 ;     INTO THE BIOS KEYBOARD BUFFER AND
  107.        MOV     DS:[BIOS_TAIL],BX       ; (9) UPDATE THE KEYBOARD TAIL POINTER.
  108.        STI
  109.        MOV     AL,DUP_DELAY2           ; (10) FINALLY, SET TICK COUNTER FOR THE
  110.        MOV     DUP_CNT,AL              ;      THE HIGHER BETWEEN-KEY REPEAT RATE.
  111. REG_RESTORE:
  112.        POP     AX                      ; (11) RESTORE REGISTERS WE USED.
  113.        POP     BX
  114.        POP     DI
  115.        POP     DS
  116. MOVE_ON:
  117.        JMP     DWORD PTR ROM_INT8      ;GO DO STANDARD TIMER INTERRUPT WORK.
  118. ;*****************************************************************************
  119. INITIALIZE:                    ;INITIALIZE INTERRUPT VECTORS 8 AND 9.
  120. ;*****************************************************************************
  121.        ASSUME  DS:CSEG
  122.        XOR     AX,AX
  123.        MOV     ES,AX                  ;SET ES TO ABSOLUTE 0 (START OF VECTORS).
  124.        MOV     AX,ES:[8*4]            ; AX=OFFSET ADDRESS TO CURRENT TIMER CODE.
  125.        MOV     BX,ES:[8*4+2]          ; BX=SEGMENT ADDRESS OF CURRENT TIMER CODE
  126.        MOV     CX,ES:[9*4]            ; CX=OFFSET ADDRESS TO ROM KEYSTROKE CODE.
  127.        MOV     DX,ES:[9*4+2]          ; DX=SEGMENT ADDRESS OF ROM KEYSTROKE CODE
  128.        MOV     ROM_INT8,AX
  129.        MOV     ROM_INT8[2],BX         ;SAVE CURRENT ADDRESSES FOR LATER USE.
  130.        MOV     ROM_INT9,CX
  131.        MOV     ROM_INT9[2],DX
  132.        CLI
  133.        LEA     AX,INT8                ;AX=OFFSET TO OUR TIMER CODE.
  134.        MOV     ES:[8*4],AX            ;RESET TIMER VECTOR TO POINT TO OUR
  135.        MOV     ES:[8*4+2],CS          ;OFFSET AND CODE SEGMENT.
  136.        LEA     AX,INT9                ;AX=OFFSET TO OUR KEYSTROKE CODE.
  137.        MOV     ES:[9*4],AX            ;RESET KEYSTROKE VECTOR TO POINT TO
  138.        MOV     ES:[9*4+2],CS          ;OUR OFFSET AND CODE SEGMENT.
  139.        STI
  140.        LEA     DX,INITIALIZE          ;POINT TO END OF CODE WE NEED TO KEEP
  141.        INT     27H                    ;AND TERMINATE SETUP OPERATION.
  142. CSEG   ENDS
  143.        END     BEGIN
  144.